(function (fruit, util) {
    //

    fruit.ui.define("fruit.graphic.GeneralTopology", {
        events: ["Ready"],
        view: {
            props: {
                'class': 'f-generalTopology',
                style: {
                    width: "{#width}",
                    height: "{#height}"
                }
            },
            content: [
                {
                    name: 'topo',
                    type: 'fruit.graphic.Topology'
                },
                {
                    name: 'sidebar',
                    type: 'fruit.graphic.GeneralTopologySidebar',
                    props: {
                        activatedItemIndex: -1
                    }
                }
            ]
        },
        properties: {
            width: {
                value: null,
                observable: true
            },
            height: {
                value: null,
                observable: true
            },
            topo: {
                getter: function () {
                    return this.$("topo");
                }
            },
            sidebar: {
                getter: function () {
                    return this.$("sidebar");
                }
            },
            nodeTooltipClass: {
                value: fruit.graphic.GeneralTopologyNodeToolTip,
                observable: true
            },
            nodeTooltipContentGenerator: {
                value: function (model) {
                    var keysArray = [];
                    util.each(model, function (value, key) {
                        if (value != null && !util.isObject(value) && key != "router config") {
                            keysArray.push({
                                value: value,
                                key: key
                            });
                        }
                    });
                    this.$("list").items(keysArray);
                },
                observable: true
            },
            linkTooltipClass: {
                value: fruit.graphic.GeneralTopologyLinkToolTip,
                observable: true
            },
            linkTooltipContentGenerator: {
                value: function (model) {
                    this.content(model.id);
                },
                observable: true
            }
        },
        methods: {
            onInit: function () {


                var topo = this.topo();
                new fruit.Binding({
                    targetPath: "width",
                    target: this,
                    sourcePath: "width",
                    source: topo
                });
                new fruit.Binding({
                    targetPath: "height",
                    target: this,
                    sourcePath: "height",
                    source: topo,
                    twoWay: false
                });


                new fruit.Binding({
                    targetPath: "height",
                    target: this.sidebar(),
                    sourcePath: "height",
                    source: topo,
                    twoWay: false
                });


            },
            setData: function (d) {
               // this.destroy();
                this.$("topo").setData(d);
            },
            start: function () {
                this.$("topo").start();
                this.__binding();
                this.__init();
                this.fire("Ready");
            },
            __binding: function () {

            },

            __init: function () {
                var self = this;
                var ele_bound;
                var node_tooltip, link_tooltip;
                var upading = false;
                var padding = this.topo().padding();
                if (!this.node_tooltip) {
                    var node_tooltip_class = this.nodeTooltipClass();
                    node_tooltip = this.node_tooltip = new node_tooltip_class();
                } else {
                    node_tooltip = this.node_tooltip;
                    node_tooltip.close(true);
                }

                if (!this.link_tooltip) {
                    var link_tooltip_class = this.linkTooltipClass();
                    link_tooltip = this.link_tooltip = new link_tooltip_class();
                } else {
                    link_tooltip = this.link_tooltip;
                    link_tooltip.close(true);
                }


                var topo = this.topo();
                var unSelectedTimer, selectedTimer;

                this.selectNode = function (node) {

                };


                this.unSelectedNode = function () {

                };

                this.overNode = function (node) {
                    if (!upading) {
                        var generator = self.nodeTooltipContentGenerator();
                        var nodeBound = node.position();
                        topo.highlightNode(node);v






                        ele_bound = self.getBound();
                        node_tooltip.title(node.label());
                        node_tooltip.model(node.data);
                        generator.call(node_tooltip, node.data);
                        node_tooltip.open({
                            target: {
                                x: ele_bound.left + nodeBound.x,
                                y: ele_bound.top + nodeBound.y
                            },
                            offsetX: 0 + node.size() * node.scale() / 2 ,
                            offsetY: 0
                        });
                    }
                };

                this.outNode = function (node) {
                    node_tooltip.close();
                    topo.recover();
                };


                topo.on("SelectNode", function (sender, node) {
                    self.selectNode(node);
                });


                topo.on("OverNode", function (sender, node) {
                    selectedTimer = setTimeout(function () {
                        self.overNode(node);
                    }, 200);
                });
                topo.on("OutNode", function (sender, node) {
                    unSelectedTimer = setTimeout(function () {
                        self.outNode(node);
                    }, 100);
                    clearTimeout(selectedTimer);
                });


                topo.on("DragNodeStart", function (sender, node) {
                    upading = true;
                    if (self.dragNodeStart) {
                        self.dragNodeStart.call(self, node);
                    }
                });

                topo.on("DragNode", function (sender, node) {
                    upading = true;
                    if (self.dragNode) {
                        self.dragNode.call(self, node);
                    }
                });


                topo.on("DragNodeEnd", function (sender, node) {
                    upading = false;
                    if (self.dragNodeEnd) {
                        self.dragNodeEnd.call(self, node);
                    }
                });


                this.overLink = function (link) {
                    if (!upading) {
                        var position = d3.mouse(link.node());
                        var generator = self.linkTooltipContentGenerator();
                        ele_bound = self.getBound();
                        generator.call(link_tooltip, link.data);
                        link_tooltip.open({
                            position: "bottom",
                            target: {
                                x: position[0] + ele_bound.left,
                                y: position[1] + ele_bound.top
                            },
                            offsetY: 10
                        });

                        //link.getSourceNode();
                        link.highLight(null, 2);
                    }
                };

                this.outLink = function (link) {
                    link_tooltip.close();
                    link.recover();
                };

                topo.on("OverLink", function (sender, link) {
                    self.overLink(link);
                });

                topo.on("OutLink", function (sender, link) {
                    self.outLink(link);
                });

                this.updating = function () {
                    upading = true;
                    self.outNode();
                    node_tooltip.close(true);
                    clearTimeout(selectedTimer);
                };


                var updatingTimer;
                topo.on("Updating", function () {
                    self.updating();
                    updatingTimer && clearTimeout(updatingTimer);

                    updatingTimer = setTimeout(function () {
                        upading = false;
                    }, 300);
                });


                this.clickStage = function () {

                };

                topo.on("ClickStage", function () {
                    self.clickStage();
                });

                node_tooltip.on("MOUSEENTER", function (sender, event) {
                    clearTimeout(unSelectedTimer);
                });
                node_tooltip.on("MOUSELEAVE", function (sender, event) {
                    self.outNode();
                });


            }





        }
    });


})(fruit, fruit.util);